/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2025-08-08     73554       the first version
 */
#include <rtthread.h>
#include <board.h>

#include "drv_spi.h"
#include "spi_flash_sfud.h"


#define DBG_TAG "storage"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

#include "user_config.h"


#define THREADTIMECYCLE            5000
/*********************************************************************************/

/*********************************************************************************/
sfud_flash *g_pSfudDev_s = NULL;
/*********************************************************************************/

/*********************************************************************************/
/* 挂载设备到SPI总线，并向内核注册SPI设备
  *  设备为 spi10，即SPI1总线上的第0号设备
  *  设置SPI片选引脚
 * */
int w25q_spi_device_init()
{
    __HAL_RCC_GPIOD_CLK_ENABLE();
    return rt_hw_spi_device_attach("spi1", "spi10", GPIOD, GPIO_PIN_2);
}
INIT_DEVICE_EXPORT(w25q_spi_device_init);
/*********************************************************************************/

/*********************************************************************************/
/* 通过SFUD驱动库和SPI设备探测SPI Flash
 * */
int rt_hw_spi_flash_with_sfud_init(void)
{
    if (RT_NULL == rt_sfud_flash_probe("W25Q128", "spi10"))
    {
        return RT_ERROR;
    }

    g_pSfudDev_s = rt_sfud_flash_find("spi10");
    if(g_pSfudDev_s == RT_NULL)
    {
        return RT_ERROR;
    }

    return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init);
/*********************************************************************************/

/*********************************************************************************/
/* Flash校验函数
 */
void L_CheckFlash(void)
{
    static uint32_t s_DataAddr_u32 = 0;
    static uint8_t s_WriteData_u8 = 0, s_CommErrCnt_u8 = 0;
    uint8_t l_ReadData_u8 = 0;
    sfud_err ret;

    //地址
    if((s_DataAddr_u32 += 4096) > 16384000) // 4096Bytes/sector, 4096sector/chip
    {
        s_DataAddr_u32 = 0;
    }
    LOG_D("W25Q128 Addr: %d ", s_DataAddr_u32);

    //写入
    s_WriteData_u8 ++;
    ret = sfud_erase_write(g_pSfudDev_s, s_DataAddr_u32, 1, &s_WriteData_u8);
    if(ret == SFUD_SUCCESS)
    {
        LOG_D("write: %d ", s_WriteData_u8);
    }
    else
    {
        s_CommErrCnt_u8++;
        LOG_W("W25Q128 write err !");
    }

    //读取
    ret = sfud_read(g_pSfudDev_s, s_DataAddr_u32, 1, &l_ReadData_u8);
    if(ret == SFUD_SUCCESS)
    {
        LOG_D("read: %d ", l_ReadData_u8);
    }
    else
    {
        s_CommErrCnt_u8++;
        LOG_W("W25Q128 read err !");
    }

    //判断
    if(l_ReadData_u8 != s_WriteData_u8)
    {
        if(++s_CommErrCnt_u8 > 1)
        {
            s_CommErrCnt_u8 = 1;
            LOG_E("comm err !");
        }
    }
    else
    {
        s_CommErrCnt_u8 = 0;
    }
}
/*********************************************************************************/

/*********************************************************************************/

/*********************************************************************************/
/* EEPROM校验函数
 * at24c08
 */
void L_CheckEEPROM(void)
{
    static uint32_t s_Addr_u32 = 0;
    static uint8_t s_WriteData_u8 = 0, s_CommErrCnt_u8 = 0;
    uint8_t l_ReadData_u8 = 0;

    //地址
    if(s_Addr_u32++ > 1000)
    {
        s_Addr_u32 = 0;
    }
    rt_thread_delay(10);

    //写入
    s_WriteData_u8++;
    g_eeprom_s->AddrInput = (uint8_t)(s_Addr_u32 >> 8);
    if(at24cxx_write(g_eeprom_s, s_Addr_u32, &s_WriteData_u8, 1) != RT_EOK)
    {
        LOG_W("at24c08 wrire err ! addrw:%d, dataw:%d.", s_Addr_u32, s_WriteData_u8);
    }
    else
    {
        LOG_D("at24c08 wrire addrw:%d, dataw:%d.", s_Addr_u32, s_WriteData_u8);
    }
    rt_thread_delay(10);

    //读取
    g_eeprom_s->AddrInput = (uint8_t)(s_Addr_u32 >> 8);
    if(at24cxx_read(g_eeprom_s, s_Addr_u32, &l_ReadData_u8, 1) != RT_EOK)
    {
        LOG_W("at24c08 read err ! addrr:%d, datar:%d.", s_Addr_u32, l_ReadData_u8);
    }
    else
    {
        LOG_D("at24c08 read addrr:%d, datar:%d.",s_Addr_u32, l_ReadData_u8);
    }

    //比对
    if(l_ReadData_u8 != s_WriteData_u8)
    {
        if(++s_CommErrCnt_u8 > 2)
        {
            s_CommErrCnt_u8 = 2;
            LOG_E("comm err !");
        }
    }
    else
    {
        s_CommErrCnt_u8 = 0;
    }
}
/*********************************************************************************/

/*********************************************************************************/
/* Storage线程入口函数
 */
void G_Storage_thread_entry(void *parameter)
{

    G_AT24CxxInit_e();

    while(1)
    {
        //Flash
        L_CheckFlash();

        //EEPROM
        L_CheckEEPROM();

        rt_thread_delay(THREADTIMECYCLE);
    }
}
/*********************************************************************************/

/*********************************************************************************/
/* 初始化Storage线程
 */
int G_InitStorageThread_i32()
{
    rt_thread_t thread8 = rt_thread_create("Storage_serial", G_Storage_thread_entry, RT_NULL, 4096, 23, 300);
    if(thread8 != RT_NULL)
    {
        rt_thread_startup(thread8);
        LOG_I("run Storage Sensor.");
    }
    else
    {
        LOG_E("create Storage thread failed !");
        return RT_ERROR;
    }

    return RT_EOK;
}
/*********************************************************************************/

/*********************************************************************************/
